<template>
  <!-- 折线图带面积 -->
  <div class="chart-wrapper">
    <div :id="chartId" class="chart" :style="getChartStyle"></div>
  </div>
</template>

<script>
import * as echarts from 'echarts';

export default {
  name: 'LineChartArea',
  props: {
    /**
     * 图表标题
     * @example '趋势数据分析'
     */
    title: {
      type: String,
      default: '',
    },

    primaryData: {
      type: Object,
      default: () => ({}),
    },
    secondaryData: {
      type: Object,
      default: () => ({}),
    },

    /**
     * 图表配置项
     * @description 图表的详细配置，包括提示框、坐标轴等
     */
    chartConfig: {
      type: Object,
      default: () => ({
        // 提示框配置
        tooltip: {
          show: true,
          trigger: 'axis',
        },
        // 网格配置
        grid: {
          left: '3%',
          right: '4%',
          bottom: '3%',
          containLabel: true,
        },
        // X轴配置
        xAxis: {
          show: true,
          axisLine: { show: true },
          axisTick: { show: true },
          axisLabel: {
            color: '#333',
            fontSize: 12,
          },
        },
        // Y轴配置
        yAxis: {
          show: true,
          axisLine: { show: true },
          axisTick: { show: true },
          axisLabel: {
            color: '#333',
            fontSize: 12,
          },
          splitLine: {
            show: true,
            lineStyle: {
              type: 'dashed',
            },
          },
        },
        // 系列配置
        series: {
          symbol: 'circle',
          symbolSize: 8,
          lineStyle: {
            width: 3,
          },
          label: {
            show: false,
            position: 'top',
          },
          areaStyle: {
            opacity: 0.1,
          },
        },
      }),
    },

    /**
     * PPT导出配置
     * @description PPT导出时的样式和布局配置
     */
    pptConfig: {
      type: Object,
      default: () => ({
        // 图表位置和大小
        position: {
          x: 5.5,
          y: 1.7,
          w: 4.5,
          h: 3.5,
        },
        // 标题配置
        title: {
          x: 5.5,
          y: 1.2,
          fontSize: 16,
          color: '363636',
          bold: true,
        },
        // 图表配置
        chart: {
          catAxisLabelFontSize: 10,
          showLegend: true,
          legendPos: 'b',
          chartColorsOpacity: 50,
          valAxisLabelRotate: 5,
          showValue: false,
          barGrouping: 'stacked',
          dataLabelFontSize: 8,
          // 平滑曲线
          lineSmooth: false,
        },
      }),
    },
  },

  data() {
    return {
      // echarts实例
      chart: null,
      chartId: Math.random().toString(36).substring(2, 15),
    };
  },
  computed: {
    // 图表样式
    getChartStyle() {
      return {
        height: this.chartConfig.height + 'px',
      };
    },

    // 根据数据量自动计算x轴标签配置
    getXAxisLabelConfig() {
      const dataLength = this.primaryData.categories?.length || 0;

      // 根据数据量自动调整配置
      if (dataLength <= 15) {
        // 数据量少时，显示所有标签，不旋转
        return {
          show: true,
          interval: 0,
          rotate: 0,
          fontSize: 12,
          color: '#333',
          margin: 8,
        };
      } else {
        // 大量数据，自动间隔，垂直显示，小字体
        return {
          show: true,
          interval: 'auto',
          rotate: 45,
          fontSize: 11,
          color: '#333',
          margin: 15,
        };
      }
    },
  },
  methods: {
    /**
     * 初始化图表
     * @description 创建echarts实例并首次渲染
     */
    initChart() {
      const chartDom = document.getElementById(this.chartId);
      if (!chartDom) return;

      this.chart = echarts.init(chartDom);
      this.updateChart();
    },

    /**
     * 更新图表数据和配置
     * @description 根据props更新图表的数据和配置项
     */
    updateChart() {
      if (!this.chart) return;
      const option = {
        // 添加标题配置
        title: {
          text: this.title,
          left: 'center',
          textStyle: {
            fontSize: 16,
            color: '#333',
          },
        },
        // 添加提示框配置
        tooltip: {
          ...this.chartConfig.tooltip,
        },
        // 添加图例配置
        legend: {
          data: [this.primaryData.name, this.secondaryData.name],
          ...this.chartConfig.legend,
        },

        xAxis: {
          ...this.chartConfig.xAxis,
          type: 'category',
          boundaryGap: false,
          data: this.primaryData.categories,
          axisLabel: {
            ...this.getXAxisLabelConfig,
            ...this.chartConfig.xAxis?.axisLabel,
          },
        },
        yAxis: {
          ...this.chartConfig.yAxis,
          type: 'value',
        },
        series: [
          {
            name: this.primaryData.name,
            type: 'line',
            data: this.primaryData.values,
            // symbol: 'center', // 隐藏数据点
            ...this.chartConfig.series,
            // 应用主系列的特定配置
            ...(this.chartConfig.series?.primary || {}),
            // 应用主系列颜色配置
            itemStyle: {
              color: this.chartConfig.colors?.[0] || '#5470c6',
              ...(this.chartConfig.series?.itemStyle || {}),
              ...(this.chartConfig.series?.primary?.itemStyle || {}),
            },
            lineStyle: {
              color: this.chartConfig.colors?.[0] || '#5470c6',
              width: 0, // 隐藏线条
              ...(this.chartConfig.series?.lineStyle || {}),
              ...(this.chartConfig.series?.primary?.lineStyle || {}),
            },
            areaStyle: {
              color: this.chartConfig.colors?.[0] || '#5470c6',
              opacity: 0.5,
              ...this.chartConfig.series?.areaStyle,
              ...(this.chartConfig.series?.primary?.areaStyle || {}),
            },
          },
          {
            name: this.secondaryData.name,
            type: 'line',
            data: this.secondaryData.values,
            // symbol: 'center', // 隐藏数据点
            ...this.chartConfig.series,
            // 应用次系列的特定配置
            ...(this.chartConfig.series?.secondary || {}),
            // 应用次系列颜色配置
            itemStyle: {
              color: this.chartConfig.colors?.[1] || '#91cc75',
              ...(this.chartConfig.series?.itemStyle || {}),
              ...(this.chartConfig.series?.secondary?.itemStyle || {}),
            },
            lineStyle: {
              color: this.chartConfig.colors?.[1] || '#91cc75',
              width: 0, // 隐藏线条
              ...(this.chartConfig.series?.lineStyle || {}),
              ...(this.chartConfig.series?.secondary?.lineStyle || {}),
            },
            areaStyle: {
              color: this.chartConfig.colors?.[1] || '#91cc75',
              opacity: 0.5,
              ...this.chartConfig.series?.areaStyle,
              ...(this.chartConfig.series?.secondary?.areaStyle || {}),
            },
          },
        ],
      };

      this.chart.setOption(option);
    },

    /**
     * 调整图表大小
     * @description 在容器大小变化时自动调整图表大小
     */
    resizeChart() {
      this.chart && this.chart.resize();
    },

    /**
     * 导出为PPT
     * @description 将图表导出为PPT格式
     * @param {Object} pptx pptxgen实例
     * @param {Object} slide 当前幻灯片实例
     */
    exportToPPT(pptx, slide) {
      // 添加图表标题
      slide.addText(this.title, {
        x: this.pptConfig.title.x,
        y: this.pptConfig.title.y,
        fontSize: this.pptConfig.title.fontSize,
        color: this.pptConfig.title.color,
        bold: this.pptConfig.title.bold,
      });
      // 添加折线图
      slide.addChart(
        pptx.charts.AREA,
        [
          {
            name: this.primaryData.name,
            labels: this.primaryData.categories,
            values: this.primaryData.values,
          },
          {
            name: this.secondaryData.name,
            labels: this.secondaryData.categories,
            values: this.secondaryData.values,
          },
        ],
        {
          x: this.pptConfig.position.x,
          y: this.pptConfig.position.y,
          w: this.pptConfig.position.w,
          h: this.pptConfig.position.h,
          // 分类轴字体大小
          catAxisLabelFontSize: this.pptConfig.chart.catAxisLabelFontSize == null ? 8 : this.pptConfig.chart.catAxisLabelFontSize,
          // 图表颜色
          chartColors: this.chartConfig.colors,
          // 图例
          showLegend: this.pptConfig.chart.showLegend == null ? true : this.pptConfig.chart.showLegend,
          // 图例位置
          legendPos: this.pptConfig.chart.legendPos == null ? 'b' : this.pptConfig.chart.legendPos,
          // 显示值
          showValue: this.pptConfig.chart.showValue == null ? false : this.pptConfig.chart.showValue,
          // 图表颜色透明度
          chartColorsOpacity: this.pptConfig.chart.chartColorsOpacity == null ? 50 : this.pptConfig.chart.chartColorsOpacity,
          // 数据标签字体大小
          dataLabelFontSize: this.pptConfig.chart.dataLabelFontSize == null ? 8 : this.pptConfig.chart.dataLabelFontSize,
          // 平滑曲线
          lineSmooth: this.chartConfig.series.lineSmooth == null ? false : this.chartConfig.series.lineSmooth,
        }
      );
    },
  },

  watch: {
    /**
     * 监听数据变化
     * @description 当数据变化时自动更新图表
     */
    values: {
      handler() {
        this.updateChart();
      },
      deep: true,
    },
    chartConfig: {
      handler() {
        this.updateChart();
      },
      deep: true,
    },
  },

  mounted() {
    this.$nextTick(() => {
      this.initChart();
      window.addEventListener('resize', this.resizeChart);
    });
  },

  beforeDestroy() {
    window.removeEventListener('resize', this.resizeChart);
    this.chart && this.chart.dispose();
    this.chart = null;
  },
};
</script>

<style lang="less" scoped>
.chart-wrapper {
  width: 100%;
  .chart {
    height: 400px;
    width: 100%;
  }
}
</style>
